{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " TDD 核心循环回顾\n",
    "\n",
    "1. **编写一个失败的测试**（从需求出发描述行为）。\n",
    "2. **运行测试并确认失败**（确保测试能够捕捉到功能缺失）。\n",
    "3. **编写最小实现代码让测试通过**。\n",
    "4. **重构与整理**（可在保持测试绿灯的前提下进行整理）。\n",
    "5. **重复上述步骤，逐步扩展功能。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 准备阶段：最小工程骨架"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./00/uniqueptr.hpp), [test_uniqueptr.cpp](./00/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 构建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-- The CXX compiler identification is GNU 11.4.0\n",
      "-- Detecting CXX compiler ABI info\n",
      "-- Detecting CXX compiler ABI info - done\n",
      "-- Check for working CXX compiler: /usr/bin/c++ - skipped\n",
      "-- Detecting CXX compile features\n",
      "-- Detecting CXX compile features - done\n",
      "-- smart_ptr_tdd_01 execution - /mnt/d/dev_learn/learn_program_language_notes/cpp/learncppbyai/smart_ptr_tdd/00\n",
      "-- Found GTest: /usr/lib/x86_64-linux-gnu/cmake/GTest/GTestConfig.cmake (found version \"1.11.0\")  \n",
      "-- Found Threads: TRUE  \n",
      "-- Configuring done\n",
      "-- Generating done\n",
      "-- Build files have been written to: /mnt/d/dev_learn/learn_program_language_notes/cpp/learncppbyai/build\n",
      "gmake: Warning: File 'Makefile' has modification time 76 s in the future\n",
      "gmake[1]: Warning: File 'CMakeFiles/Makefile2' has modification time 76 s in the future\n",
      "gmake[2]: Warning: File 'smart_ptr_tdd/00/CMakeFiles/smart_ptr_tdd_01.dir/flags.make' has modification time 76 s in the future\n",
      "gmake[2]: warning:  Clock skew detected.  Your build may be incomplete.\n",
      "gmake[2]: Warning: File 'smart_ptr_tdd/00/CMakeFiles/smart_ptr_tdd_01.dir/flags.make' has modification time 76 s in the future\n",
      "[ 50%] Building CXX object smart_ptr_tdd/00/CMakeFiles/smart_ptr_tdd_01.dir/uniqueptr_test.cpp.o\n",
      "[100%] Linking CXX executable smart_ptr_tdd_01\n",
      "gmake[2]: warning:  Clock skew detected.  Your build may be incomplete.\n",
      "[100%] Built target smart_ptr_tdd_01\n",
      "gmake[1]: warning:  Clock skew detected.  Your build may be incomplete.\n",
      "gmake: warning:  Clock skew detected.  Your build may be incomplete.\n"
     ]
    }
   ],
   "source": [
    "! cd ../ && rm -rf build && cmake -S . -B build && cmake --build build"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 执行测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Internal ctest changing into directory: /mnt/d/dev_learn/learn_program_language_notes/cpp/learncppbyai/build/smart_ptr_tdd/01\n",
      "Test project /mnt/d/dev_learn/learn_program_language_notes/cpp/learncppbyai/build/smart_ptr_tdd/01\n",
      "    Start 1: UniquePtrInitialTest.Compiles\n",
      "1/1 Test #1: UniquePtrInitialTest.Compiles ....   Passed    0.01 sec\n",
      "\n",
      "100% tests passed, 0 tests failed out of 1\n",
      "\n",
      "Total Test time (real) =   0.04 sec\n"
     ]
    }
   ],
   "source": [
    "! cd ../ && ctest --test-dir build/smart_ptr_tdd/00 --output-on-failure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者直接执行可执行文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 1 test from 1 test suite.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 1 test from 1 test suite ran. (0 ms total)\n",
      "[  PASSED  ] 1 test.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/00 && ./smart_ptr_tdd_00"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 1 步：默认构造后应为空"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./01/uniqueptr.hpp), [test_uniqueptr.cpp](./01/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- 默认构造后 `get() == nullptr`\n",
    "- 转换为 `bool` 为 `false`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 2 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 1 test from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[----------] 1 test from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 2 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 2 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/01 && ./smart_ptr_tdd_01"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  第 2 步：支持 `nullptr` 构造"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- `UniquePtr ptr(nullptr);` 的行为与默认构造一致"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./02/uniqueptr.hpp), [uniqueptr_test.cpp](./02/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 3 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 2 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[----------] 2 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 3 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 3 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/02 && ./smart_ptr_tdd_02"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 3 步：以裸指针构造并访问对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- 以 `new` 出来的指针构造\n",
    "- 支持 `get()`、`operator->()`、`operator*()` 访问对象成员"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./03/uniqueptr.hpp), [uniqueptr_test.cpp](./03/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 4 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 3 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[----------] 3 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 4 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 4 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/03 && ./smart_ptr_tdd_03"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 4 步：析构时释放资源"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- 离开作用域时释放资源（借助计数器类 `Counter` 验证）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./04/uniqueptr.hpp), [uniqueptr_test.cpp](./04/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 5 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 4 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[----------] 4 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 5 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 5 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/04 && ./smart_ptr_tdd_04"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 5 步：`reset` 释放旧资源并接管新资源"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- `reset(new T)`：先释放旧资源，再接管新资源\n",
    "- `reset()`：释放资源后指针为空"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./05/uniqueptr.hpp), [uniqueptr_test.cpp](./05/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 7 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 6 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[----------] 6 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 7 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 7 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/05 && ./smart_ptr_tdd_05"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 6 步：`release` 放弃所有权但不删除对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- `release()` 返回原始指针，内部状态置空，但不调用删除器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./06/uniqueptr.hpp), [uniqueptr_test.cpp](./06/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 8 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 7 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting\n",
      "[       OK ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting (0 ms)\n",
      "[----------] 7 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 8 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 8 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/06 && ./smart_ptr_tdd_06"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 7 步：`swap` 交换两个智能指针的资源"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- `a.swap(b)` 互换资源\n",
    "- 支持 `swap(a, b)`（依赖 ADL，需提供非成员重载）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./07/uniqueptr.hpp), [uniqueptr_test.cpp](./07/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 9 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 8 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting\n",
      "[       OK ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting (0 ms)\n",
      "[ RUN      ] UniquePtrTest.SwapExchangesPointers\n",
      "[       OK ] UniquePtrTest.SwapExchangesPointers (0 ms)\n",
      "[----------] 8 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 9 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 9 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/07 && ./smart_ptr_tdd_07"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 8 步：实现移动语义（移动构造与移动赋值）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- 移动构造后：源对象指针为空，新对象接管资源\n",
    "- 移动赋值后：目标释放旧资源，接管源资源，源置空\n",
    "- 禁止拷贝语义（编译期）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./08/uniqueptr.hpp), [uniqueptr_test.cpp](./08/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 11 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 10 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting\n",
      "[       OK ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting (0 ms)\n",
      "[ RUN      ] UniquePtrTest.SwapExchangesPointers\n",
      "[       OK ] UniquePtrTest.SwapExchangesPointers (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveConstructionTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveConstructionTransfersOwnership (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveAssignmentTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveAssignmentTransfersOwnership (0 ms)\n",
      "[----------] 10 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 11 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 11 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/08 && ./smart_ptr_tdd_08"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 9 步：使用 GoogleMock 验证自定义删除器被调用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- 使用 GoogleMock 验证自定义删除器被调用\n",
    "- 通过 `get_deleter()` 取得当前删除器并调用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./09/uniqueptr.hpp), [uniqueptr_test.cpp](./09/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 13 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 12 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting\n",
      "[       OK ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting (0 ms)\n",
      "[ RUN      ] UniquePtrTest.SwapExchangesPointers\n",
      "[       OK ] UniquePtrTest.SwapExchangesPointers (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveConstructionTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveConstructionTransfersOwnership (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveAssignmentTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveAssignmentTransfersOwnership (0 ms)\n",
      "[ RUN      ] UniquePtrTest.CustomDeleterIsInvokedOnDestruction\n",
      "[       OK ] UniquePtrTest.CustomDeleterIsInvokedOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.GetDeleterReturnsCurrentDeleter\n",
      "[       OK ] UniquePtrTest.GetDeleterReturnsCurrentDeleter (0 ms)\n",
      "[----------] 12 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 13 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 13 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/09 && ./smart_ptr_tdd_09"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 10 步：实现 `make_unique`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "新增测试点\n",
    "\n",
    "- `make_unique` 能完美转发构造参数，返回 `UniquePtr`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [uniqueptr.hpp](./10/uniqueptr.hpp), [uniqueptr_test.cpp](./10/uniqueptr_test.cpp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running main() from ./googletest/src/gtest_main.cc\n",
      "[==========] Running 13 tests from 2 test suites.\n",
      "[----------] Global test environment set-up.\n",
      "[----------] 1 test from UniquePtrInitialTest\n",
      "[ RUN      ] UniquePtrInitialTest.Compiles\n",
      "[       OK ] UniquePtrInitialTest.Compiles (0 ms)\n",
      "[----------] 1 test from UniquePtrInitialTest (0 ms total)\n",
      "\n",
      "[----------] 12 tests from UniquePtrTest\n",
      "[ RUN      ] UniquePtrTest.DefaultConstructedIsNull\n",
      "[       OK ] UniquePtrTest.DefaultConstructedIsNull (0 ms)\n",
      "[ RUN      ] UniquePtrTest.NullptrConstructionBehavesLikeDefault\n",
      "[       OK ] UniquePtrTest.NullptrConstructionBehavesLikeDefault (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ConstructWithRawPointerAndAccess\n",
      "[       OK ] UniquePtrTest.ConstructWithRawPointerAndAccess (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleasesResourceOnDestruction\n",
      "[       OK ] UniquePtrTest.ReleasesResourceOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetReleasesOldAndTakesNew\n",
      "[       OK ] UniquePtrTest.ResetReleasesOldAndTakesNew (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ResetWithoutArgReleasesResource\n",
      "[       OK ] UniquePtrTest.ResetWithoutArgReleasesResource (0 ms)\n",
      "[ RUN      ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting\n",
      "[       OK ] UniquePtrTest.ReleaseReturnsRawPointerWithoutDeleting (0 ms)\n",
      "[ RUN      ] UniquePtrTest.SwapExchangesPointers\n",
      "[       OK ] UniquePtrTest.SwapExchangesPointers (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveConstructionTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveConstructionTransfersOwnership (0 ms)\n",
      "[ RUN      ] UniquePtrTest.MoveAssignmentTransfersOwnership\n",
      "[       OK ] UniquePtrTest.MoveAssignmentTransfersOwnership (0 ms)\n",
      "[ RUN      ] UniquePtrTest.CustomDeleterIsInvokedOnDestruction\n",
      "[       OK ] UniquePtrTest.CustomDeleterIsInvokedOnDestruction (0 ms)\n",
      "[ RUN      ] UniquePtrTest.GetDeleterReturnsCurrentDeleter\n",
      "[       OK ] UniquePtrTest.GetDeleterReturnsCurrentDeleter (0 ms)\n",
      "[----------] 12 tests from UniquePtrTest (0 ms total)\n",
      "\n",
      "[----------] Global test environment tear-down\n",
      "[==========] 13 tests from 2 test suites ran. (0 ms total)\n",
      "[  PASSED  ] 13 tests.\n"
     ]
    }
   ],
   "source": [
    "! cd ../build/smart_ptr_tdd/09 && ./smart_ptr_tdd_09"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "C++17",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
